package ptij.ADSL.de.ATUC;

import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.*;
import ptolemy.actor.*;
import ptolemy.actor.gui.*;
import ptolemy.data.expr.*;
import ptolemy.data.type.*;
import ptolemy.data.*;
import ptolemy.domains.de.kernel.*;
import ptolemy.domains.de.lib.TimedDelay;

import ptij.ADSL.common.NullO;
import ptij.ADSL.common.Timer;

//////////////////////////////////////////////////////////////////////////
//// ATUC
/**

@author Ivan Jeukens
*/
public class ATUC extends TypedCompositeActor {        
        
    public ATUC(CompositeEntity container, String name) throws
            NameDuplicationException, IllegalActionException {        
	super(container, name);
	
	dataTx = new TypedIOPort(this, "dataTx_C", true, false);
	dataTx.setTypeEquals(BaseType.INT);
	
	AS0 = new TypedIOPort(this, "AS0_C", true, false);
	AS0.setTypeEquals(BaseType.OBJECT);

        rx = new TypedIOPort(this, "rx_C", true, false);
	if(dftInputMode == 0) {
	    rx.setTypeEquals(BaseType.DOUBLE);
	}
	else
	if(dftInputMode == 1) {
	    rx.setTypeEquals(BaseType.OBJECT);
	}
	else {
	    throw new IllegalActionException(this, "Invalid dft input mode");
	}
	
	LS0_in = new TypedIOPort(this, "LS0_in_C", true, false);
	LS0_in.setTypeEquals(BaseType.OBJECT);

	LS0_out = new TypedIOPort(this, "LS0_out_C", false, true);
	LS0_out.setTypeEquals(BaseType.OBJECT);

        tx = new TypedIOPort(this, "tx_C", false, true);
	if(idftOutputMode == 0) {
	    tx.setTypeEquals(BaseType.DOUBLE);
	}
	else
	if(idftOutputMode == 1) {
	    tx.setTypeEquals(BaseType.OBJECT);
	}
	else {
	    throw new IllegalActionException(this, "invalid idft output mode");
	}

        /* TX */
        
        _muxtx = new MuxSyncTx(this, "MuxSyncTx_C");
	_muxtx.AS0Bytes.setToken(new IntToken(AS0Bytes_C));
	_muxtx.LS0Bytes.setToken(new IntToken(LS0Bytes_C));
	_muxtx.AS0Map.setToken(new BooleanToken(AS0Map_C));
	_muxtx.LS0Map.setToken(new BooleanToken(LS0Map_C));
	_muxtx.S.setToken(new IntToken(S_C));

        /*
	_crcTx = new CRCTx(this, "crcTx");
	_crcTx.AS0Bytes.setToken(new IntToken(AS0Bytes_C));
	_crcTx.LS0Bytes.setToken(new IntToken(LS0Bytes_C));
	_crcTx.AS0Map.setToken(new BooleanToken(AS0Map_C));
	_crcTx.LS0Map.setToken(new BooleanToken(LS0Map_C));
	_crcTx.S.setToken(new IntToken(S_C));

        _scramblerTx = new ScramblerTx(this, "scramblerTx");
	_scramblerTx.AS0Bytes.setToken(new IntToken(AS0Bytes_C));
	_scramblerTx.LS0Bytes.setToken(new IntToken(LS0Bytes_C));
	_scramblerTx.AS0Map.setToken(new BooleanToken(AS0Map_C));
	_scramblerTx.LS0Map.setToken(new BooleanToken(LS0Map_C));
	_scramblerTx.S.setToken(new IntToken(S_C));

	_fectx = new FECTx(this, "FECTx");
	_fectx.AS0Bytes.setToken(new IntToken(AS0Bytes_C));
	_fectx.LS0Bytes.setToken(new IntToken(LS0Bytes_C));
        _fectx.AS0Map.setToken(new BooleanToken(AS0Map_C));
	_fectx.LS0Map.setToken(new BooleanToken(LS0Map_C));
	_fectx.S.setToken(new IntToken(S_C));
	_fectx.parityFast.setToken(new IntToken(parityFast_C));
	_fectx.parityInter.setToken(new IntToken(parityInter_C));

	_interTx = new InterleaverTx(this, "interTx");
	_interTx.AS0Bytes.setToken(new IntToken(AS0Bytes_C));
	_interTx.LS0Bytes.setToken(new IntToken(LS0Bytes_C));
	_interTx.AS0Map.setToken(new BooleanToken(AS0Map_C));
	_interTx.LS0Map.setToken(new BooleanToken(LS0Map_C));
	_interTx.S.setToken(new IntToken(S_C));
	_interTx.parityInter.setToken(new IntToken(parityInter_C));
	_interTx.D.setToken(new IntToken(D_C));

	_map = new Map(this, "Map");
	_map.AS0Bytes.setToken(new IntToken(AS0Bytes_C));
	_map.LS0Bytes.setToken(new IntToken(LS0Bytes_C));
        _map.AS0Map.setToken(new BooleanToken(AS0Map_C));
	_map.LS0Map.setToken(new BooleanToken(LS0Map_C));
	_map.S.setToken(new IntToken(S_C));
	_map.parityFast.setToken(new IntToken(parityFast_C));
	_map.parityInter.setToken(new IntToken(parityInter_C));
        _map.outputMode.setExpression("1");

        _idft = new IDFT(this, "IDFT");
        _idft.inputMode.setExpression("1");
        _idft.outputMode.setExpression("1"); */
        
        /* RX */
        
/*        
	_dft = new DFT(this, "DFT");
        _dft.inputMode.setExpression("1");
        _dft.outputMode.setExpression("1");

	_demap = new Demap(this, "Demap");
	_demap.LS0Bytes.setToken(new IntToken(LS0Bytes_R));
	_demap.LS0Map.setToken(new BooleanToken(LS0Map_R));
	_demap.S.setToken(new IntToken(S_R));
        _demap.parityFast.setToken(new IntToken(parityFast_R));
	_demap.parityInter.setToken(new IntToken(parityInter_R));
        _demap.inputMode.setExpression("1");

	_interRx = new InterleaverRx(this, "interRx");
	_interRx.LS0Bytes.setToken(new IntToken(LS0Bytes_R));
	_interRx.LS0Map.setToken(new BooleanToken(LS0Map_R));
	_interRx.S.setToken(new IntToken(S_R));
	_interRx.parityInter.setToken(new IntToken(parityInter_R));
	_interRx.D.setToken(new IntToken(D_R));
	    	    
        _fecrx = new FECRx(this, "FECRx");
	_fecrx.LS0Bytes.setToken(new IntToken(LS0Bytes_R));
	_fecrx.LS0Map.setToken(new BooleanToken(LS0Map_R));
	_fecrx.S.setToken(new IntToken(S_R));
	_fecrx.parityFast.setToken(new IntToken(parityFast_R)); 
	_fecrx.parityInter.setToken(new IntToken(parityInter_R));

        _scramblerRx = new ScramblerRx(this, "scramblerRx");
	_scramblerRx.LS0Bytes.setToken(new IntToken(LS0Bytes_R));
	_scramblerRx.LS0Map.setToken(new BooleanToken(LS0Map_R));
	_scramblerRx.S.setToken(new IntToken(S_R));

        _crcRx = new CRCRx(this, "crcRx");
        _crcRx.LS0Bytes.setToken(new IntToken(LS0Bytes_R));
	_crcRx.LS0Map.setToken(new BooleanToken(LS0Map_R));
	_crcRx.S.setToken(new IntToken(S_R)); */

	_muxrx = new MuxSyncRx(this, "MuxSyncRx_C");
	_muxrx.S.setToken(new IntToken(S_R));

        /* Control */
	
        /*
        _init = new Initializer(this, "Initializer");
        _init.inputMode.setExpression("1");
        _init.outputMode.setExpression("1");
	_timer = new Timer(this, "Timer"); */

        /* TX Path */
	
        connect(AS0, _muxtx.AS0);
	connect(LS0_in, _muxtx.LS0);
	connect(dataTx, _muxtx.dataTx);
        
        connect(_muxtx.output, tx);

        /*     	
        connect(_muxtx.output, _crcTx.input);
	connect(_crcTx.output, _scramblerTx.input); 
	connect(_scramblerTx.output, _fectx.input);
	connect(_fectx.fast, _map.fast);	
        connect(_fectx.inter, _interTx.input);
	connect(_interTx.output, _map.inter);

        if(toATURMode == 0) {
	    for(int i = 0;i < 255;i++)
	        connect(_map.subChannel[i], _idft.subChannel[i]);
	}
	else {
	    connect(_map.subChannel[0], _idft.subChannel[0]);
	}
	    
	connect(_idft.output, tx);
*/

        /* Rx Path */
	/*
        connect(rx, _dft.input);
	
	if(fromATURMode == 0) {
	    for(int i = 0;i < 31;i++)
	        connect(_dft.subChannel[i], _demap.subChannel[i]);
	}
	else {
            connect(_dft.subChannel[0], _demap.subChannel[0]);
	}

	connect(_demap.inter, _interRx.input);
	connect(_interRx.output, _fecrx.inter);
	connect(_demap.fast, _fecrx.fast);
	connect(_fecrx.output, _scramblerRx.input);
	connect(_scramblerRx.output, _crcRx.input);	
	connect(_crcRx.output, _muxrx.input); */
        
        connect(rx, _muxrx.input);
        
	connect(_muxrx.LS0, LS0_out);
	
	/* Control */
	
        /*NullO no = new NullO(this, "nullo");
	connect(no.output, _init.reset);
	connect(_init.start, _muxtx.start);
	connect(_init.idftMode, _idft.mode);
	connect(_init.dftMode, _dft.mode);

        if(toATURMode == 0) {
	    for(int i = 0;i < 255;i++) 
	        connect(_init.toATUR[i], _idft.subChannel[i]);
	}
	else {
	    connect(_init.toATUR[0], _idft.subChannel[0]);
	}

        if(fromATURMode == 0) {
	    for(int i = 0;i < 31;i++)
	        connect(_dft.subChannel[i], _init.fromATUR[i]);
	}
	else {
            connect(_dft.subChannel[0], _init.fromATUR[0]);
	}
	    
	TimedDelay d1 = new TimedDelay(this, "ATUC_delay1");
	connect(_init.startTimer, _timer.startTimer);
	connect(_init.stopTimer, _timer.stopTimer);	
	connect(_timer.timerEvent, d1.input);
	connect(d1.output, _init.timerEvent); */
    }

    ///////////////////////////////////////////////////////////////////
    ////                     ports and parameters                  ////
    
    public TypedIOPort dataTx;
    public TypedIOPort AS0;
    public TypedIOPort rx;
    public TypedIOPort LS0_in;
        
    public TypedIOPort tx;
    public TypedIOPort LS0_out;

    public static final int AS0Bytes_C = 25;
    public static final boolean AS0Map_C = false;
    public static final int LS0Bytes_C = 31;
    public static final boolean LS0Map_C = true;
    public static final int S_C = 2;
    public static final int parityFast_C = 2;
    public static final int parityInter_C = 2;
    public static final int D_C = 2;

    public static final int LS0Bytes_R = 5;
    public static final boolean LS0Map_R = true;
    public static final int S_R = 2;
    public static final int parityFast_R = 0;
    public static final int parityInter_R = 2;
    public static final int D_R = 2;

    public static final int framesPerSuperframe = 6;
        
    public static final int toATURMode = 1;
    public static final int fromATURMode = 1;
    public static final int idftOutputMode = 1;
    public static final int dftInputMode = 1;
    
    ///////////////////////////////////////////////////////////////////
    ////                         private variables                 ////            
    
    private MuxSyncTx _muxtx;
    private CRCTx _crcTx;
    private ScramblerTx _scramblerTx;
    private FECTx _fectx;
    private InterleaverTx _interTx;
    private Map _map;
    private IDFT _idft;

    private DFT _dft;
    private Demap _demap;
    private InterleaverRx _interRx;
    private FECRx _fecrx;
    private ScramblerRx _scramblerRx;
    private CRCRx _crcRx;
    private MuxSyncRx _muxrx;
    
    private Initializer _init;
    private Timer _timer;
}
